package com.sisyphus.simple.data;

import com.sisyphus.mock.MockApplicationServer;
import com.sisyphus.simple.data.network.WebServiceApi;
import com.sisyphus.simple.data.network.model.BaseListResponse;
import com.sisyphus.simple.data.network.model.BaseResponse;
import com.sisyphus.simple.data.network.model.ListResponse;
import com.sisyphus.simple.data.network.model.Post;
import com.sisyphus.simple.data.network.model.User;
import com.sisyphus.spinach.core.INetTask;
import com.sisyphus.spinach.core.INetPageTask;
import com.sisyphus.spinach.core.model.IPageResponse;
import com.sisyphus.spinach.core.model.IResponse;
import com.sisyphus.spinach.network.presenters.NetPageTask;
import com.sisyphus.spinach.network.presenters.NetSingleTask;

import java.util.List;
import java.util.concurrent.TimeUnit;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import io.reactivex.rxjava3.core.Observable;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class DataRepository {

    private static DataRepository sDataRepository;

    public static DataRepository getInstance() {
        if (sDataRepository == null) {
            synchronized (DataRepository.class) {
                if (sDataRepository == null) {
                    sDataRepository = new DataRepository();
                }
            }
        }

        return sDataRepository;
    }


    private final WebServiceApi mWebServiceApi;

    private DataRepository() {
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .addNetworkInterceptor(logInterceptor)
                .build();

        mWebServiceApi = new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(MockApplicationServer.getHostAddress())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(WebServiceApi.class);
    }

    public Observable<BaseResponse<Object>> register(
            String email,
            String password,
            String nickname
    ) {

        return mWebServiceApi.register(email, password, nickname);
    }

    public Observable<BaseResponse<User>> login(
            String email,
            String password
    ) {

        return mWebServiceApi.login(email, password);
    }

    public INetPageTask.Presenter<Post, INetPageTask.View<Post>> posts() {
        return new NetPageTask<Post>() {
            @Override
            public Observable<? extends IResponse<? extends IPageResponse<Post>>> execute(int page) {
                return mWebServiceApi.list(page, ListResponse.PAGE_NUMBER);
            }
        };
    }

    public INetTask.Presenter<List<Post>, INetTask.View<List<Post>>> hot() {
        return new NetSingleTask<List<Post>, INetTask.View<List<Post>>>(mWebServiceApi.hot()) {
            @Override
            public void onResume(@NonNull LifecycleOwner owner) {
                execute();
            }
        };
    }

    public Observable<BaseListResponse<Post>> postFavorite(int page, int number){
        return mWebServiceApi.postFavorite(page, number);
    }

}
